package de.hauschild.orbitvm.controller.impl;

import java.awt.Color;

import javax.swing.JLabel;

import de.hauschild.orbitvm.visualization.VMFrame;
import de.hauschild.orbitvm.vm.DoublePoint;
import de.hauschild.orbitvm.vm.VM;

public class MeetAndGreetController extends AbstractController {

  private final JLabel targetPositionLabel;
  private final JLabel targetDistanceLabel;
  private DoublePoint startImpulse;
  private DoublePoint stopImpulse;
  private boolean stoped;

  public MeetAndGreetController(final VM theVM, final VMFrame theVMFrame) {
    super(theVM, theVMFrame);

    targetPositionLabel = theVMFrame.createControllerLabel("Target position:");
    targetDistanceLabel = theVMFrame.createControllerLabel("Distance to target:");
  }

  @Override
  protected void afterIteration() {
    final DoublePoint targetSatellitePosition = getTargetSatellitePosition();
    targetPositionLabel.setText(String.format("%.2f / %.2f", targetSatellitePosition.getX(), targetSatellitePosition
        .getY()));
    final double targetDistance = getTargetDistance();
    targetDistanceLabel.setForeground(Color.RED);
    targetDistanceLabel.setText(String.format(DOUBLE_FORMAT_STRING, targetDistance));
    if (targetDistance < ONE_KILOMETER) {
      targetDistanceLabel.setForeground(Color.GREEN);
    }
    if (vmFrame().getImageGraphics() != null) {
      final int targetRadius = (int) (getTargetSatelliteOrbitRadius() / VMFrame.SIZE_FACTOR);
      vmFrame().getImageGraphics().setColor(Color.GREEN);
      vmFrame().getImageGraphics().drawOval(VMFrame.IMAGE_SIZE / 2 - targetRadius,
          VMFrame.IMAGE_SIZE / 2 - targetRadius, 2 * targetRadius, 2 * targetRadius);
      final Double x = getTargetSatellitePosition().getX() / VMFrame.SIZE_FACTOR + VMFrame.IMAGE_SIZE / 2;
      final Double y = -getTargetSatellitePosition().getY() / VMFrame.SIZE_FACTOR + VMFrame.IMAGE_SIZE / 2;
      vmFrame().drawPixel(x.intValue(), y.intValue(), Color.GREEN);
    }
    vmFrame().repaint();
  }

  @Override
  protected void beforeIteration() {
    if (getIteration() == 7400) {
      startImpulse = HohmannController.getStartImpulse(vm(), getTargetSatelliteOrbitRadius());
      stopImpulse = HohmannController.getStopImpulse(vm(), getTargetSatelliteOrbitRadius());
      vm().setVelocityImpulse(startImpulse);
    }
    if (Math.abs(getTargetSatelliteOrbitRadius() - vm().getDistanceToEarth()) < 1000.0 && !stoped) {
      vm().setVelocityImpulse(stopImpulse);
      stoped = true;
    }
  }

  protected double getTargetDistance() {
    return Math.sqrt((getTargetSatellitePosition().getX() - vm().getSatellitePosition().getX())
        * (getTargetSatellitePosition().getX() - vm().getSatellitePosition().getX())
        + (getTargetSatellitePosition().getY() - vm().getSatellitePosition().getY())
        * (getTargetSatellitePosition().getY() - vm().getSatellitePosition().getY()));
  }

  protected double getTargetSatelliteOrbitRadius() {
    return getTargetSatellitePosition().length();
  }

  protected DoublePoint getTargetSatellitePosition() {
    return new DoublePoint(getTargetSatelliteRelaivePosition().getX() - vm().getSatellitePosition().getX(),
        getTargetSatelliteRelaivePosition().getY() - vm().getSatellitePosition().getY());
  }

  protected DoublePoint getTargetSatelliteRelaivePosition() {
    return new DoublePoint(vm().getOutput()[4], vm().getOutput()[5]);
  }

  @Override
  protected void initialize() {
    startImpulse = HohmannController.getStartImpulse(vm(), getTargetSatelliteOrbitRadius());
    stopImpulse = HohmannController.getStopImpulse(vm(), getTargetSatelliteOrbitRadius());
  }

}
